﻿// -------------------------------------------------------------------------
//    @FileName         :    NFCacheDataGetTrans.h
//    @Author           :    gaoyi
//    @Date             :    2025-08-12
//    @Email			:    445267987@qq.com
//    @Module           :    NFCacheDataGetTrans
//    @Desc             :    缓存数据获取事务基类声明
//                           提供批量缓存数据获取的统一接口和子事务管理
//                           支持批量/单条查询、插入操作的事务协调
//
// -------------------------------------------------------------------------

/**
 * @file NFCacheDataGetTransBase.h
 * @brief 缓存数据获取事务基类定义
 *
 * 提供缓存数据批量/单条获取事务的统一接口，作为具体缓存数据
 * 获取事务的基类，便于在共享内存事务系统中统一创建与调度。
 */

#pragma once

#include "NFComm/NFObjCommon/NFTransBase.h"
#include "NFServerTypeDefine.h"

class NFCacheDataWithSaveDb;
/**
 * @class NFCacheDataGetTrans
 * @brief 缓存数据获取事务基类（共享内存事务对象）
 *
 * 职责：
 * - 定义获取缓存数据的对外请求接口与回包回调接口
 * - 管理子事务的创建与调度
 * - 提供批量操作的协调机制
 *
 * 使用流程：
 * 1. 业务层创建具体子类实例并调用 Init() 初始化
 * 2. 调用 GetCacheDataBatchReq() 发起批量或单条查询
 * 3. 内部创建 NFCacheDataTrans 子事务处理具体查询
 * 4. 子事务完成后回调 GetCacheDataBatchRes() 处理结果
 *
 * 使用约定：
 * - 具体业务应继承该类并实现请求与结果处理逻辑
 * - 该类对象由共享内存对象管理器统一创建与回收
 * - 支持批量操作，内部自动拆分为多个子事务并发处理
 *
 * 设计特点：
 * - 通过事务类型参数支持不同数据表的查询
 * - 提供统一的错误处理和事务清理机制
 * - 支持父子事务的嵌套调用和结果回调
 */
class NFCacheDataGetTrans : public NF_OBJECT_TEMPLATE_MACRO(NFCacheDataGetTrans, EOT_TRANS_GET_CACHE_DATA_BASE_OBJ, NFTransBase)
public:
    /**
     * @brief 构造函数，根据共享内存模式进行初始化
     * 
     * 根据共享内存管理器的创建模式选择初始化方式：
     * - EN_OBJ_MODE_INIT：冷启动模式，调用 CreateInit() 进行完整初始化
     * - 其他模式：热启动模式，调用 ResumeInit() 进行恢复初始化
     */
    NFCacheDataGetTrans();

    /**
     * @brief 析构函数
     * 
     * 清理资源，由于使用共享内存管理，通常无需特殊处理
     */
    ~NFCacheDataGetTrans() override;

    /**
     * @brief 冷启动创建初始化
     * 
     * 在共享内存冷启动场景下，对所有成员变量进行零值初始化
     * 
     * @return 0 表示成功
     */
    int CreateInit();

    /**
     * @brief 热启动恢复初始化
     * 
     * 在共享内存热启动场景下，从持久化数据恢复对象状态时调用
     * 
     * @return 0 表示成功
     */
    int ResumeInit();

public:
    /**
     * @brief 初始化事务运行参数
     * 
     * 设置事务执行所需的基本参数，通常在创建事务后立即调用
     * 
     * @param serverType 目标存储服务器类型
     * @param roleId      目标对象ID
     * @param tableId     数据表ID，用于标识要操作的数据表
     * @return 0 表示成功
     */
    virtual int Init(int serverType, uint64_t roleId, int tableId);

public:
    /**
     * @brief 批量获取缓存数据请求（模板版本）
     * 
     * 使用模板参数简化调用，自动推导事务类型：
     * 1. 通过模板参数获取具体的事务类型
     * 2. 调用非模板版本的批量查询方法
     * 3. 提供更简洁的API接口
     * 
     * @tparam CacheDataTrans 具体的事务类型
     * @param vecId     ID列表
     * @param enReason   调用原因/场景标识
     * @param iTableId   数据表ID（可选，为0时使用当前表ID）
     * @return 0 表示成功，其他值为错误码
     */
    template <typename CacheDataTrans>
    int GetCacheDataBatchReq(const std::vector<uint64_t>& vecId, int enReason, int iTableId = 0)
    {
        return GetCacheDataBatchReq(CacheDataTrans::GetStaticClassType(), vecId, enReason, iTableId);
    }

    /**
     * @brief 单条获取缓存数据请求（模板版本）
     * 
     * 使用模板参数简化调用，自动推导事务类型：
     * 1. 通过模板参数获取具体的事务类型
     * 2. 调用非模板版本的单条查询方法
     * 3. 提供更简洁的API接口
     * 
     * @tparam CacheDataTrans 具体的事务类型
     * @param ullId     目标ID
     * @param enReason  调用原因/场景标识
     * @param iTableId  数据表ID（可选，为0时使用当前表ID）
     * @return 0 表示成功，其他值为错误码
     */
    template <typename CacheDataTrans>
    int GetCacheDataSingleReq(uint64_t ullId, int enReason, int iTableId = 0)
    {
        return GetCacheDataSingleReq(CacheDataTrans::GetStaticClassType(), ullId, enReason, iTableId);
    }

    /**
     * @brief 单条获取缓存数据请求（带 Protobuf 数据，模板版本）
     *
     * 使用模板参数简化调用，自动推导事务类型：
     * 1. 通过模板参数获取具体的事务类型
     * 2. 调用非模板版本的单条查询方法
     * 3. 提供更简洁的 API 接口
     *
     * @tparam CacheDataTrans 具体的事务类型
     * @param ullId     目标对象的唯一标识 ID
     * @param enReason  调用原因/场景标识
     * @param stData    Protobuf 消息对象，包含查询所需的额外信息
     * @param iTableId  数据表 ID（可选，为 0 时使用当前表 ID）
     * @return 0 表示成功，其他值为错误码
     *
     * @note 此方法通过模板封装，便于调用者简化代码逻辑。
     * @warning 调用前需确保 `stData` 包含完整且正确的查询信息，避免因数据不完整导致的查询失败。
     */
    template <typename CacheDataTrans>
    int GetCacheDataSingleReq(uint64_t ullId, int enReason, const google::protobuf::Message& stData, int iTableId = 0)
    {
        return GetCacheDataSingleReq(CacheDataTrans::GetStaticClassType(), ullId, enReason, stData, iTableId);
    }

    /**
     * @brief 发起缓存数据保存请求（模板版本，带 Protobuf 数据）
     *
     * 使用模板参数简化调用，自动推导事务类型：
     * 1. 通过模板参数获取具体的事务类型
     * 2. 调用非模板版本的保存方法
     * 3. 提供更简洁的 API 接口
     *
     * @tparam CacheDataTrans 具体的事务类型
     * @param ullId     目标对象的唯一标识 ID
     * @param iReason   调用原因/场景标识
     * @param stPbClass Protobuf 消息对象，包含要保存的数据
     * @param iTableId  数据表 ID（可选，为 0 时使用当前表 ID）
     * @return 0 表示成功，其他值为错误码
     *
     * @note 此方法通过事务机制实现数据保存，确保操作的原子性与一致性。
     * @warning 调用前需确保 `stPbClass` 包含完整且正确的保存信息，避免因数据不完整导致的保存失败。
     */
    template <typename CacheDataTrans>
    int SaveCacheDataReq(uint64_t ullId, int iReason, const google::protobuf::Message& stPbClass, int iTableId = 0)
    {
        return SaveCacheDataReq(CacheDataTrans::GetStaticClassType(), ullId, iReason, stPbClass, iTableId);
    }

    template <typename CacheDataTrans>
    int SaveCacheDataReq(uint64_t ullId, int iReason, const google::protobuf::Message& stPbClass, NFCacheDataWithSaveDb* pSaveDb, int iTableId = 0)
    {
        return SaveCacheDataReq(CacheDataTrans::GetStaticClassType(), ullId, iReason, stPbClass, pSaveDb, iTableId);
    }

    /**
     * @brief 获取缓存数据返回处理（基类默认实现）
     * 
     * 虚函数，子类应重写此方法实现具体的批量查询结果处理逻辑。
     * 基类实现仅输出警告信息，提醒开发者需要在子类中实现。
     * 
     * @param ullId     目标ID
     * @param iTableId  表ID/类型
     * @param iReason   调用原因
     * @param errCode   错误码
     * @param pMessage
     * @return 0 表示成功
     */
    virtual int GetCacheDataRes(int ullId, int iTableId, int iReason, int32_t errCode, google::protobuf::Message* pMessage);

    /**
     * @brief 获取缓存数据结果处理
     *
     * 该虚函数用于处理缓存数据获取的结果，子类应重写此方法以实现具体的结果处理逻辑。
     *
     * @param ullId     目标对象的唯一标识 ID
     * @param iTableId  数据表 ID/类型标识
     * @param iReason   调用原因/场景标识
     * @param errCode   错误码，表示操作结果
     * @return int 返回处理结果的状态码，通常返回 0 表示成功，非 0 表示失败或错误码
     *
     * @note
     * - 子类需根据业务需求实现该方法，处理查询结果或错误码。
     * - 基类默认实现可能为空或仅输出警告信息。
     * - 确保在子类实现中处理所有可能的错误码和边界情况。
     */
    virtual int OnGetCacheDataFinish(int ullId, int iTableId, int iReason, int32_t errCode);

    /**
     * @brief 插入缓存数据批量返回处理（基类默认实现）
     * 
     * 虚函数，子类应重写此方法实现具体的批量插入结果处理逻辑。
     * 基类实现仅输出警告信息，提醒开发者需要在子类中实现。
     * 
     * @param ullId     目标对象的唯一标识ID
     * @param iTableId  数据表ID/类型
     * @param iReason   调用原因/场景标识
     * @param errCode   错误码，表示操作结果
     * @param pMessage
     * @return 0 表示成功
     */
    virtual int InsertCacheDataRes(int ullId, int iTableId, int iReason, int32_t errCode, google::protobuf::Message* pMessage);

    /**
     * @brief 插入缓存数据完成后的回调处理
     *
     * 该虚函数用于处理缓存数据插入操作完成后的结果，子类应重写此方法以实现具体的结果处理逻辑。
     *
     * @param ullId     目标对象的唯一标识 ID
     * @param iTableId  数据表 ID/类型标识
     * @param iReason   调用原因/场景标识
     * @param errCode   错误码，表示操作结果
     * @return int 返回处理结果的状态码，通常返回 0 表示成功，非 0 表示失败或错误码
     *
     * @note
     * - 子类需根据业务需求实现该方法，处理插入结果或错误码。
     * - 基类默认实现可能为空或仅输出警告信息。
     * - 确保在子类实现中处理所有可能的错误码和边界情况。
     */
    virtual int OnInsertCacheDataFinish(int ullId, int iTableId, int iReason, int32_t errCode);

    /**
     * @brief 保存缓存数据批量返回处理（基类默认实现）
     *
     * 虚函数，子类应重写此方法实现具体的批量保存结果处理逻辑。
     * 基类实现仅输出警告信息，提醒开发者需要在子类中实现。
     *
     * @param ullId     目标对象的唯一标识ID
     * @param iTableId  数据表ID/类型
     * @param iReason   调用原因/场景标识
     * @param errCode   错误码，表示操作结果
     * @return 0 表示成功
     */
    virtual int SaveCacheDataRes(int ullId, int iTableId, int iReason, int32_t errCode);

public:
    /**
     * @brief 批量获取缓存数据请求
     * 
     * 创建并初始化子事务来处理批量查询：
     * 1. 更新表ID（如果提供）
     * 2. 创建指定类型的加载事务对象
     * 3. 初始化子事务参数
     * 4. 发起批量查询请求
     * 
     * @param loadTransType 加载事务类型
     * @param vecId         ID列表
     * @param enReason      调用原因/场景标识
     * @param iTableId      数据表ID（可选，为0时使用当前表ID）
     * @return 0 表示成功，其他值为错误码
     */
    virtual int GetCacheDataBatchReq(int loadTransType, const std::vector<uint64_t>& vecId, int enReason, int iTableId = 0);

    /**
     * @brief 单条获取缓存数据请求
     * 
     * 创建并初始化子事务来处理单条查询：
     * 1. 更新表ID（如果提供）
     * 2. 创建指定类型的加载事务对象
     * 3. 初始化子事务参数
     * 4. 发起单条查询请求
     * 
     * @param loadTransType 加载事务类型
     * @param ullId         目标ID
     * @param enReason      调用原因/场景标识
     * @param iTableId      数据表ID（可选，为0时使用当前表ID）
     * @return 0 表示成功，其他值为错误码
     */
    virtual int GetCacheDataSingleReq(int loadTransType, uint64_t ullId, int enReason, int iTableId = 0);

    /**
     * @brief 单条获取缓存数据请求（带 Protobuf 数据）
     *
     * 创建并初始化子事务来处理单条查询：
     * 1. 更新表 ID（如果提供）
     * 2. 创建指定类型的加载事务对象
     * 3. 初始化子事务参数
     * 4. 发起单条查询请求
     *
     * @param loadTransType 加载事务类型
     * @param ullId         目标对象的唯一标识 ID
     * @param enReason      调用原因/场景标识
     * @param stData        Protobuf 消息对象，包含查询所需的额外信息
     * @param iTableId      数据表 ID（可选，为 0 时使用当前表 ID）
     * @return 0 表示成功，其他值为错误码
     */
    virtual int GetCacheDataSingleReq(int loadTransType, uint64_t ullId, int enReason, const google::protobuf::Message& stData, int iTableId = 0);

    /**
     * @brief 发起缓存数据插入请求（带Protobuf消息）
     * 
     * 创建并初始化子事务来处理数据插入：
     * 1. 更新表ID（如果提供）
     * 2. 创建指定类型的插入事务对象
     * 3. 初始化子事务参数
     * 4. 发起插入请求
     * 
     * @param insertTransType 插入事务类型
     * @param ullId           目标ID
     * @param iReason         调用原因
     * @param stPbClass       Protobuf消息对象，包含要插入的数据
     * @param iTableId        数据表ID（可选，为0时使用当前表ID）
     * @return 0 表示成功，其他值为错误码
     */
    virtual int InsertCacheDataReq(int insertTransType, uint64_t ullId, int iReason, const google::protobuf::Message& stPbClass, int iTableId = 0);

    /**
     * @brief 发起缓存数据插入请求（不带Protobuf消息）
     * 
     * 创建并初始化子事务来处理数据插入：
     * 1. 更新表ID（如果提供）
     * 2. 创建指定类型的插入事务对象
     * 3. 初始化子事务参数
     * 4. 发起插入请求（子事务内部会构造默认的Protobuf消息）
     * 
     * @param insertTransType 插入事务类型
     * @param ullId           目标ID
     * @param iReason         调用原因
     * @param iTableId        数据表ID（可选，为0时使用当前表ID）
     * @return 0 表示成功，其他值为错误码
     */
    virtual int InsertCacheDataReq(int insertTransType, uint64_t ullId, int iReason, int iTableId = 0);

    /**
     * @brief 发起缓存数据保存请求
     *
     * 创建并初始化子事务来处理数据保存：
     * 1. 更新表 ID（如果提供）
     * 2. 创建指定类型的保存事务对象
     * 3. 初始化子事务参数
     * 4. 发起保存请求
     *
     * @param saveTransType 保存事务类型
     * @param ullId         目标对象的唯一标识 ID
     * @param iReason       调用原因/场景标识
     * @param stPbClass     Protobuf 消息对象，包含要保存的数据
     * @param iTableId      数据表 ID（可选，为 0 时使用当前表 ID）
     * @return 0 表示成功，其他值为错误码
     *
     * @note 此方法通过事务机制实现数据保存，确保操作的原子性与一致性。
     * @warning 调用前需确保 `stPbClass` 包含完整且正确的保存信息，避免因数据不完整导致的保存失败。
     */
    virtual int SaveCacheDataReq(int saveTransType, uint64_t ullId, int iReason, const google::protobuf::Message& stPbClass, int iTableId = 0);

    /**
     * @brief 发起缓存数据保存请求（带 Protobuf 数据和自定义保存对象）
     *
     * 创建并初始化子事务来处理数据保存：
     * 1. 更新表 ID（如果提供）
     * 2. 创建指定类型的保存事务对象
     * 3. 初始化子事务参数
     * 4. 发起保存请求
     *
     * @param saveTransType 保存事务类型
     * @param ullId         目标对象的唯一标识 ID
     * @param iReason       调用原因/场景标识
     * @param stPbClass     Protobuf 消息对象，包含要保存的数据
     * @param pSaveDb       自定义保存对象，用于扩展保存逻辑
     * @param iTableId      数据表 ID（可选，为 0 时使用当前表 ID）
     * @return 0 表示成功，其他值为错误码
     *
     * @note 此方法通过事务机制实现数据保存，确保操作的原子性与一致性。
     * @warning 调用前需确保 `stPbClass` 和 `pSaveDb` 包含完整且正确的保存信息，避免因数据不完整导致的保存失败。
     */
    virtual int SaveCacheDataReq(int saveTransType, uint64_t ullId, int iReason, const google::protobuf::Message& stPbClass, NFCacheDataWithSaveDb* pSaveDb, int iTableId = 0);

    /**
     * @brief 发起缓存数据插入请求（模板版本，带Protobuf消息）
     * 
     * 使用模板参数简化调用，自动推导事务类型：
     * 1. 通过模板参数获取具体的事务类型
     * 2. 调用非模板版本的插入方法
     * 3. 提供更简洁的API接口
     * 
     * @tparam CacheDataTrans 具体的事务类型
     * @param ullId           目标ID
     * @param iReason         调用原因
     * @param stPbClass       Protobuf消息对象，包含要插入的数据
     * @param iTableId        数据表ID（可选，为0时使用当前表ID）
     * @return 0 表示成功，其他值为错误码
     */
    template <typename CacheDataTrans>
    int InsertCacheDataReq(uint64_t ullId, int iReason, const google::protobuf::Message& stPbClass, int iTableId = 0)
    {
        return InsertCacheDataReq(CacheDataTrans::GetStaticClassType(), ullId, iReason, stPbClass, iTableId);
    }

    /**
     * @brief 发起缓存数据插入请求（模板版本，不带Protobuf消息）
     * 
     * 使用模板参数简化调用，自动推导事务类型：
     * 1. 通过模板参数获取具体的事务类型
     * 2. 调用非模板版本的插入方法
     * 3. 提供更简洁的API接口
     * 
     * @tparam CacheDataTrans 具体的事务类型
     * @param ullId           目标ID
     * @param iReason         调用原因
     * @param iTableId        数据表ID（可选，为0时使用当前表ID）
     * @return 0 表示成功，其他值为错误码
     */
    template <typename CacheDataTrans>
    int InsertCacheDataReq(uint64_t ullId, int iReason, int iTableId = 0)
    {
        return InsertCacheDataReq(CacheDataTrans::GetStaticClassType(), ullId, iReason, iTableId);
    }

protected:
    /** @brief 目标存储服务器类型 */
    int m_iServerType;
    /** @brief 操作对象ID */
    uint64_t m_ullRoleId;
    /** @brief 数据表ID/类型标识 */
    int m_iTableId;
    /** @brief 调用原因/场景标识 */
    int m_iReason;
};
